package org.study.util;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.util.Calendar;
import java.util.Date;

/**
 * 该类的描述
 *
 * @author doveylovey
 * @version v1.0.0
 * @email 1135782208@qq.com
 * @date 2021-05-19
 */
public class DateUtils {
    public static void main(String[] args) throws ParseException {
        //localDateTimeTest();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String start = "2021-11-24 17:20:29";
        String end = "2021-11-24 17:34:59";
        Integer parkTime = 24;
        Long overTime = (sdf.parse(end).getTime() - sdf.parse(start).getTime() - (parkTime * 60 * 1000));
        System.out.println(overTime);
    }

    private DateUtils() {
        throw new AssertionError("不能实例化工具类！");
    }

    /**
     * 获取当前时间的毫秒值
     *
     * @return
     */
    public static long getCurrentTimeMillis() {
        return System.currentTimeMillis();
    }

    /**
     * 获取当前时间自 1970-01-01 00:00:00 纪元以来的毫秒数
     *
     * @return
     */
    public static long getCurrentEpochMilli() {
        ZoneId zoneId = ZoneId.systemDefault();
        LocalDateTime localDateTime = LocalDateTime.now();
        ZonedDateTime zonedDateTime = localDateTime.atZone(zoneId);
        Instant instant = zonedDateTime.toInstant();
        long epochMilli = instant.toEpochMilli();
        return epochMilli;
    }

    /**
     * 获取指定时间自 1970-01-01 00:00:00 纪元以来的毫秒数
     *
     * @param localDateTime 指定时间
     * @return
     */
    public static long getEpochMilli(LocalDateTime localDateTime) {
        Assert.notNull(localDateTime, "参数不能为null");
        ZoneId zoneId = ZoneId.systemDefault();
        ZonedDateTime zonedDateTime = localDateTime.atZone(zoneId);
        Instant instant = zonedDateTime.toInstant();
        long epochMilli = instant.toEpochMilli();
        return epochMilli;
    }

    /**
     * 获取当前时间自 1970-01-01 00:00:00 纪元以来的秒数
     *
     * @return
     */
    public static long getCurrentEpochSecond() {
        ZoneId zoneId = ZoneId.systemDefault();
        LocalDateTime localDateTime = LocalDateTime.now();
        ZonedDateTime zonedDateTime = localDateTime.atZone(zoneId);
        Instant instant = zonedDateTime.toInstant();
        long epochSecond = instant.getEpochSecond();
        return epochSecond;
    }

    /**
     * 获取指定时间自 1970-01-01 00:00:00 纪元以来的秒数
     *
     * @param localDateTime 指定时间
     * @return
     */
    public static long getEpochSecond(LocalDateTime localDateTime) {
        Assert.notNull(localDateTime, "参数不能为null");
        ZoneId zoneId = ZoneId.systemDefault();
        ZonedDateTime zonedDateTime = localDateTime.atZone(zoneId);
        Instant instant = zonedDateTime.toInstant();
        long epochSecond = instant.getEpochSecond();
        return epochSecond;
    }

    /**
     * 将指定毫秒值转换为 LocalDateTime
     *
     * @param milliseconds
     * @return java.time.LocalDateTime
     */
    public static LocalDateTime milliseconds2LocalDateTime(long milliseconds) {
        ZoneOffset zoneOffset = ZoneOffset.ofHours(8);
        LocalDateTime localDateTime = LocalDateTime.ofEpochSecond(milliseconds / 1000, 0, zoneOffset);
        return localDateTime;
    }

    /**
     * 将指定秒值转换为 LocalDateTime
     *
     * @param epochSecond
     * @return java.time.LocalDateTime
     */
    public static LocalDateTime second2LocalDateTime(long epochSecond) {
        ZoneOffset zoneOffset = ZoneOffset.ofHours(8);
        LocalDateTime localDateTime = LocalDateTime.ofEpochSecond(epochSecond, 0, zoneOffset);
        return localDateTime;
    }

    /**
     * 计算两个时间的时间差，返回：w天x时y分z秒
     *
     * @param startDate 开始时间
     * @param endDate   结束时间
     * @return java.lang.String
     */
    public static String differTime(Date startDate, Date endDate) {
        long milliSeconds = Math.abs(endDate.getTime() - startDate.getTime());
        String result = differTime(milliSeconds);
        return result;
    }

    /**
     * 将毫秒值转换为：w天x时y分z秒
     *
     * @param milliSeconds 毫秒值
     * @return java.lang.String
     */
    public static String differTime(long milliSeconds) {
        StringBuilder result = new StringBuilder();
        long day = milliSeconds / (24 * 60 * 60 * 1000);
        long hour = (milliSeconds / (60 * 60 * 1000) - day * 24);
        long min = ((milliSeconds / (60 * 1000)) - day * 24 * 60 - hour * 60);
        long second = (milliSeconds / 1000 - day * 24 * 60 * 60 - hour * 60 * 60 - min * 60);
        if (day > 0) {
            result.append(day + "天");
        }
        if (hour > 0) {
            result.append(hour + "时");
        }
        if (min > 0) {
            result.append(min + "分");
        }
        if (second > 0) {
            result.append(second + "秒");
        }
        return result.toString();
    }

    /**
     * 判断给定时间是否在 [startTime, endTime] 区间，注意时间格式要一致
     *
     * @param nowTime   当前时间
     * @param startTime 开始时间
     * @param endTime   结束时间
     * @return boolean
     */
    public static boolean isEffectiveDate(Date nowTime, Date startTime, Date endTime) {
        if (nowTime.equals(startTime) || nowTime.equals(endTime)) {
            return true;
        }
        if (nowTime.getTime() == startTime.getTime() || nowTime.getTime() == endTime.getTime()) {
            return true;
        }
        Calendar nowCalendar = Calendar.getInstance();
        nowCalendar.setTime(nowTime);
        Calendar beginCalendar = Calendar.getInstance();
        beginCalendar.setTime(startTime);
        Calendar endCalendar = Calendar.getInstance();
        endCalendar.setTime(endTime);
        if (nowCalendar.after(beginCalendar) && nowCalendar.before(endCalendar)) {
            return true;
        } else {
            return false;
        }
    }

    public static void localDateTimeTest() {
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        String strDateTime = "2021-11-25 00:00:00";
        String strDate = "2021-11-25";

        LocalDateTime localDateTime = LocalDateTime.now();
        //localDateTime = LocalDateTime.parse("2021-11-25 00:00:00", dateTimeFormatter1);
        LocalDate localDate = LocalDate.now();
        //localDate = LocalDate.parse("2021-11-25", dateTimeFormatter2);
        Date date = Date.from(LocalDateTime.parse(strDateTime, dateTimeFormatter).atZone(ZoneId.systemDefault()).toInstant());

        Long timestamp = System.currentTimeMillis();
        System.out.println("-------------------------------\n");
        System.out.println("LocalDateTime 转 LocalDate: " + localDateTime.toLocalDate());
        System.out.println("LocalDateTime 转 Long: " + localDateTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli());
        System.out.println("LocalDateTime 转 Date: " + Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant()));
        System.out.println("LocalDateTime 转 String: " + localDateTime.format(dateTimeFormatter));
        System.out.println("\n-------------------------------\n");
        System.out.println("LocalDate 转 LocalDateTime: " + LocalDateTime.of(localDate, LocalTime.parse("00:00:00")));
        System.out.println("LocalDate 转 Long: " + localDate.atStartOfDay(ZoneId.systemDefault()).toInstant().toEpochMilli());
        System.out.println("LocalDate 转 Date: " + Date.from(localDate.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant()));
        System.out.println("LocalDateTime 转 String: " + localDateTime.format(dateFormatter));
        System.out.println("\n-------------------------------\n");
        System.out.println("Date 转 LocalDateTime: " + LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault()));
        System.out.println("Date 转 Long: " + date.getTime());
        System.out.println("Date 转 LocalDateTime: " + LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault()).toLocalDate());
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");
        System.out.println("Date 转 String: " + sdf.format(date));
        System.out.println("\n-------------------------------\n");
        System.out.println("String 转 LocalDateTime: " + LocalDateTime.parse(strDateTime, dateTimeFormatter));
        System.out.println("String 转 LocalDate: " + LocalDateTime.parse(strDateTime, dateTimeFormatter).toLocalDate());
        System.out.println("String 转 LocalDate: " + LocalDate.parse(strDate, dateFormatter));
        System.out.println("String 转 Date: " + Date.from(LocalDateTime.parse(strDateTime, dateTimeFormatter).atZone(ZoneId.systemDefault()).toInstant()));
        System.out.println("\n-------------------------------\n");
        System.out.println("Long 转 LocalDateTime:" + LocalDateTime.ofInstant(Instant.ofEpochMilli(timestamp), ZoneId.systemDefault()));
        System.out.println("Long 转 LocalDate:" + LocalDateTime.ofInstant(Instant.ofEpochMilli(timestamp), ZoneId.systemDefault()).toLocalDate());
        System.out.println("\n-------------------------------");
    }
}
